﻿namespace SKeeper.Persistence.Repositories
{
    using SKeeper.Domain;
    using SKeeper.Domain.Repositories;
    using SKeeper.Persistence.Facade;
    using System;
    using System.Data.Entity;
    using System.Linq;
    using System.Linq.Expressions;

    public abstract class GenericRepository<T> : IRepository<T> where T : class,  IEntity 
    {
        protected DomainModelFacade db;

        public GenericRepository(DomainModelFacade context)
        {
            this.db = context;
        }

        public bool Create(T entity)
        {
            var result = db.Set<T>().Add(entity);
            
            var changes = db.SaveChanges();

            return changes != 0;
        }

        public IQueryable<T> GetIncluding(params Expression<Func<T, object>>[] include)
        {
            IQueryable<T> result = this.db.Set<T>();

            foreach (var item in include)
            {
                result = result.Include(item);
            }

            return result;
        }

        public bool Delete(T entity)
        {
            this.db.Set<T>().Remove(entity);
            var changes = this.db.SaveChanges();

            return changes != 0;
        }

        public IQueryable<T> GetAll()
        {
            return this.db.Set<T>();
        }

        public T GetById(int id)
        {
            var result = this.db.Set<T>().Find(id);
            return result;
        }

        public int SaveChanges()
        {
            var changes = this.db.SaveChanges();
            return changes;
        }

        public bool Update(T entity)
        {
            var original = db.Set<T>().Find(entity.Id);
            int changes = 0;
            if (original != null)
            {
                db.Entry(original).CurrentValues.SetValues(entity);
                changes = db.SaveChanges();
            }

            return changes != 0;
        }

        public void Dispose()
        {
            if (this.db != null)
                this.db.Dispose();
        }
    }
}
